/**************************************************************************************************
	$Header: /pub/cvsroot/mydns/src/lib/mydns.h,v 1.31 2002/07/27 01:46:34 bboy Exp $
	libmydns.h: Header file for the MyDNS library.

	Copyright (C) 2002  Don Moore <bboy@bboy.net>

	This program is free software; you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation; either version 2 of the License, or
	(at Your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program; if not, write to the Free Software
	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
**************************************************************************************************/

#ifndef _MYDNS_H
#define _MYDNS_H

#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <limits.h>
#include <ctype.h>
#include <stdlib.h>
#include <stdarg.h>
#include <errno.h>
#include <string.h>

#include <mysql.h>
#include <errmsg.h>

#include <netinet/in.h>


/* Table names */
#define	MYDNS_SOA_TABLE	"soa"
#define	MYDNS_RR_TABLE		"rr"
#define	MYDNS_PTR_TABLE	"ptr"

/* NOTE: `type' is listed at the end so that we can possibly set the value of `aux' for
	convenience based on the RR type; for example, an `A' record might store the IP in `aux'. */
#define	MYDNS_SOA_FIELDS	"id,origin,ns,mbox,serial,refresh,retry,expire,minimum,ttl"
#define	MYDNS_RR_FIELDS	"id,zone,name,data,aux,ttl,type"
#define	MYDNS_PTR_FIELDS	"id,ip,name,ttl"

/* Clear MySQL error/errno error */
#define	MYDNS_CLEARERR(m)	if (m) m->net.last_errno = 0; errno = 0;

/* Does the specified string end with a dot? */
#define	ENDS_WITH_DOT(s)	(s && (s[strlen(s)-1] == '.'))

/* Convert str to unsigned int */
#define atou(s) (u_int32_t)strtoul(s, (char **)NULL, 10)

/* Size ranges for various bits of DNS data */
#define	DNS_MAXPACKETLEN_TCP		65536		/* Use 64k for TCP */
#define	DNS_MAXPACKETLEN_UDP		512		/* RFC1035: "512 octets or less" */
#define	DNS_MAXNAMELEN				255		/* RFC1035: "255 octets or less" */
#define	DNS_MAXLABELLEN			63			/* RFC1035: "63 octets or less" */
#define	DNS_POINTER_MASK			0xC0
#define	DNS_QUERYBUFSIZ			512		/* Used as buffer size for MySQL queries */

/* Default values in SOA records */
#define	DNS_DEFAULT_REFRESH		28800
#define	DNS_DEFAULT_RETRY			7200
#define	DNS_DEFAULT_EXPIRE		604800
#define	DNS_DEFAULT_MINIMUM		86400
#define	DNS_DEFAULT_TTL			86400

/* Query classes */
#define	DNS_C_IN			1
#define	DNS_C_CHAOS		3
#define	DNS_C_HESIOD	4
#define	DNS_C_ANY		255

/* Query types */
typedef enum _dns_qtype_t
{
	DNS_T_NONE = 0,
	DNS_T_A,				/* 1 */
	DNS_T_NS,			/* 2 */

	DNS_T_003, DNS_T_004,

	DNS_T_CNAME,		/* 5 */
	DNS_T_SOA,			/* 6 */

	DNS_T_007, DNS_T_008, DNS_T_009,

	DNS_T_NULL,			/* 10 */

	DNS_T_011,

	DNS_T_PTR,			/* 12 */
	DNS_T_HINFO,		/* 13 */
	DNS_T_MINFO,		/* 14 */
	DNS_T_MX,			/* 15 */
	DNS_T_TXT,			/* 16 */

	DNS_T_017, DNS_T_018, DNS_T_019, DNS_T_020, DNS_T_021, DNS_T_022, DNS_T_023, DNS_T_024, DNS_T_025,
	DNS_T_026, DNS_T_027,

	DNS_T_AAAA,			/* 28 */

	DNS_T_029, DNS_T_030, DNS_T_031, DNS_T_032, DNS_T_033, DNS_T_034,
	DNS_T_035, DNS_T_036, DNS_T_037, DNS_T_038, DNS_T_039, DNS_T_040, DNS_T_041, DNS_T_042, DNS_T_043,
	DNS_T_044, DNS_T_045, DNS_T_046, DNS_T_047, DNS_T_048, DNS_T_049, DNS_T_050, DNS_T_051, DNS_T_052,
	DNS_T_053, DNS_T_054, DNS_T_055, DNS_T_056, DNS_T_057, DNS_T_058, DNS_T_059, DNS_T_060, DNS_T_061,
	DNS_T_062, DNS_T_063, DNS_T_064, DNS_T_065, DNS_T_066, DNS_T_067, DNS_T_068, DNS_T_069, DNS_T_070,
	DNS_T_071, DNS_T_072, DNS_T_073, DNS_T_074, DNS_T_075, DNS_T_076, DNS_T_077, DNS_T_078, DNS_T_079,
	DNS_T_080, DNS_T_081, DNS_T_082, DNS_T_083, DNS_T_084, DNS_T_085, DNS_T_086, DNS_T_087, DNS_T_088,
	DNS_T_089, DNS_T_090, DNS_T_091, DNS_T_092, DNS_T_093, DNS_T_094, DNS_T_095, DNS_T_096, DNS_T_097,
	DNS_T_098, DNS_T_099, DNS_T_100, DNS_T_101, DNS_T_102, DNS_T_103, DNS_T_104, DNS_T_105, DNS_T_106,
	DNS_T_107, DNS_T_108, DNS_T_109, DNS_T_110, DNS_T_111, DNS_T_112, DNS_T_113, DNS_T_114, DNS_T_115,
	DNS_T_116, DNS_T_117, DNS_T_118, DNS_T_119, DNS_T_120, DNS_T_121, DNS_T_122, DNS_T_123, DNS_T_124,
	DNS_T_125, DNS_T_126, DNS_T_127, DNS_T_128, DNS_T_129, DNS_T_130, DNS_T_131, DNS_T_132, DNS_T_133,
	DNS_T_134, DNS_T_135, DNS_T_136, DNS_T_137, DNS_T_138, DNS_T_139, DNS_T_140, DNS_T_141, DNS_T_142,
	DNS_T_143, DNS_T_144, DNS_T_145, DNS_T_146, DNS_T_147, DNS_T_148, DNS_T_149, DNS_T_150, DNS_T_151,
	DNS_T_152, DNS_T_153, DNS_T_154, DNS_T_155, DNS_T_156, DNS_T_157, DNS_T_158, DNS_T_159, DNS_T_160,
	DNS_T_161, DNS_T_162, DNS_T_163, DNS_T_164, DNS_T_165, DNS_T_166, DNS_T_167, DNS_T_168, DNS_T_169,
	DNS_T_170, DNS_T_171, DNS_T_172, DNS_T_173, DNS_T_174, DNS_T_175, DNS_T_176, DNS_T_177, DNS_T_178,
	DNS_T_179, DNS_T_180, DNS_T_181, DNS_T_182, DNS_T_183, DNS_T_184, DNS_T_185, DNS_T_186, DNS_T_187,
	DNS_T_188, DNS_T_189, DNS_T_190, DNS_T_191, DNS_T_192, DNS_T_193, DNS_T_194, DNS_T_195, DNS_T_196,
	DNS_T_197, DNS_T_198, DNS_T_199, DNS_T_200, DNS_T_201, DNS_T_202, DNS_T_203, DNS_T_204, DNS_T_205,
	DNS_T_206, DNS_T_207, DNS_T_208, DNS_T_209, DNS_T_210, DNS_T_211, DNS_T_212, DNS_T_213, DNS_T_214,
	DNS_T_215, DNS_T_216, DNS_T_217, DNS_T_218, DNS_T_219, DNS_T_220, DNS_T_221, DNS_T_222, DNS_T_223,
	DNS_T_224, DNS_T_225, DNS_T_226, DNS_T_227, DNS_T_228, DNS_T_229, DNS_T_230, DNS_T_231, DNS_T_232,
	DNS_T_233, DNS_T_234, DNS_T_235, DNS_T_236, DNS_T_237, DNS_T_238, DNS_T_239, DNS_T_240, DNS_T_241,
	DNS_T_242, DNS_T_243, DNS_T_244, DNS_T_245, DNS_T_246, DNS_T_247, DNS_T_248, DNS_T_249, DNS_T_250,

	DNS_T_IXFR,			/* 251 */
	DNS_T_AXFR,			/* 252 */

	DNS_T_253, DNS_T_254,

	DNS_T_ANY,			/* 255 */
} dns_qtype_t;

/* Opcodes */
typedef enum _dns_opcode_t		/* DNS opcode types */
{
	DNS_OPCODE_QUERY = 0,		/* Query */
	DNS_OPCODE_IQUERY,			/* Inverse query */
	DNS_OPCODE_STATUS				/* Status request */
} dns_opcode_t;


/* Return codes */
typedef enum _dns_rcode_t		/* DNS return codes */
{
	DNS_R_OK = 0,					/* No error */
	DNS_R_FORMERR,					/* The name server was unable to interpret the query */
	DNS_R_SERVFAIL,				/* The name server had an internal error */
	DNS_R_NXDOMAIN,				/* The specified domain name does not exist */
	DNS_R_NOTIMP,					/* The requested kind of query is not implemented */
	DNS_R_REFUSED,					/* Query refused for policy reasons */
} dns_rcode_t;

/* The record types */
typedef enum _dns_rrtype_t		/* DNS record types (for MyDNS) */
{
	DNS_RRTYPE_SOA,
	DNS_RRTYPE_RR,
	DNS_RRTYPE_PTR,
} dns_rrtype_t;


/*
**  Structures describing each record type
*/
typedef struct _mydns_soa							/* `soa' table data (zones of authority) */
{
	u_int32_t	id;
	u_char		origin[DNS_MAXNAMELEN+1];
	u_char		ns[DNS_MAXNAMELEN+1];
	u_char		mbox[DNS_MAXNAMELEN+1];
	u_int32_t	serial;
	u_int32_t	refresh;
	u_int32_t	retry;
	u_int32_t	expire;
	u_int32_t	minimum;
	u_int32_t	ttl;

	struct _mydns_soa *next;
} MYDNS_SOA;

typedef struct _mydns_rr							/* `rr' table data (resource records) */
{
	u_int32_t	id;
	u_int32_t	zone;
	u_char		name[DNS_MAXLABELLEN+1];
	dns_qtype_t	type;
	u_char		data[DNS_MAXNAMELEN+1];
	u_int64_t	aux;
	u_int32_t	ttl;

	struct _mydns_rr *next;
} MYDNS_RR;

typedef struct _mydns_ptr							/* `ptr' (ip-to-name mappings) */
{
	u_int32_t	id;
	u_int32_t	ip;
	u_char		name[DNS_MAXNAMELEN+1];
	u_int32_t	ttl;

	struct _mydns_ptr *next;
} MYDNS_PTR;


/* ip.c */
extern u_int32_t mydns_revstr_ip4(u_char *);


/* str.c */
extern char *mydns_qtype_str(dns_qtype_t);
extern char *mydns_class_str(int);
extern char *mydns_opcode_str(dns_opcode_t);
extern char *mydns_rcode_str(dns_rcode_t);

/* soa.c */
extern inline MYDNS_SOA *mydns_parse_soa(MYSQL_ROW);
extern int mydns_soa_load(MYSQL *, MYDNS_SOA **, unsigned char *);
extern MYDNS_SOA *mydns_soa_dup(MYDNS_SOA *, int);
extern inline size_t mydns_soa_size(MYDNS_SOA *);
extern inline void _mydns_soa_free(MYDNS_SOA *);
#define mydns_soa_free(p) if (p) _mydns_soa_free(p), p = NULL

/* rr.c */
extern inline MYDNS_RR *mydns_parse_rr(MYSQL_ROW);
extern int mydns_rr_load(MYSQL *, MYDNS_RR **, u_int32_t, dns_qtype_t, unsigned char *);
extern MYDNS_RR *mydns_rr_dup(MYDNS_RR *, int);
extern inline size_t mydns_rr_size(MYDNS_RR *);
extern inline void _mydns_rr_free(MYDNS_RR *);
#define mydns_rr_free(p) if (p) _mydns_rr_free(p), p = NULL

/* ptr.c */
extern inline MYDNS_PTR *mydns_parse_ptr(MYSQL_ROW);
extern int mydns_ptr_load(MYSQL *, MYDNS_PTR **, struct in_addr *);
extern MYDNS_PTR *mydns_ptr_dup(MYDNS_PTR *, int);
extern inline size_t mydns_ptr_size(MYDNS_PTR *);
extern inline void _mydns_ptr_free(MYDNS_PTR *);
#define mydns_ptr_free(p) if (p) _mydns_ptr_free(p), p = NULL

#endif /* !_MYDNS_H */

/* vi:set ts=3: */
